﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;
using System;
using System.Text;

class Person
{
	public string name;
	public int? age;
}

public class Sample : MonoBehaviour 
{
	struct TestStructType
	{
		public int a;
		public int b;
//		public TestObject t;
	}

	[DllImport("__Internal")]
	static extern void outputAppendString (string str1, string str2);

	[DllImport("__Internal")]
	static extern void outputAppendString2 (string str1, string str2, IntPtr resultHandler);

	[DllImport("__Internal")]
	static extern void testType(char p1, short p2, int p3, long p4, bool p5, string p6, TestStructType p7);

	[DllImport("__Internal")]
	static extern void printPersonInfo (IntPtr personData);

	[DllImport("__Internal")]
	static extern IntPtr returnString (out int len);


	void callback (string resultStr)
	{
		Debug.LogFormat ("result string = {0}", resultStr);
	}

	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate void ResultHandler(string resultString);

	[MonoPInvokeCallback(typeof(ResultHandler))]
	static void resultHandler (string resultStr)
	{
		Debug.LogFormat ("result string = {0}", resultStr);
	}

	// Use this for initialization
	void Start () 
	{
		#if UNITY_IPHONE	

//		outputAppendString("Hello", "World");

//		ResultHandler handler = new ResultHandler(resultHandler);
//		IntPtr fp = Marshal.GetFunctionPointerForDelegate(handler);
//		outputAppendString2 ("Hello", "World", fp);

//		Debug.Log("----------------------- 1");
//		char p1 = 'a';
//		short p2 = 0xff;
//		int p3 = 0xffff;
//		long p4 = 0xffffffff;
//		bool p5 = true;
//		string p6 = "Hello World";
//		TestStructType p7 = new TestStructType();
//		p7.a = 100;
//		p7.b = 99;
////		p7.t = new TestObject();
////		p7.t.value = "Hi";
//		testType(p1, p2, p3, p4, p5, p6, p7);
//		Debug.Log("----------------------- 2");

//		Person person = new Person();
//		person.name = "vimfung";
//		person.age = 18;
//		List<byte> buf = new List<byte>();
//
//		//写入name [4(name len)][len(content)]
//		byte[] bytes = BitConverter.GetBytes (person.name.Length);
//		if (BitConverter.IsLittleEndian)
//		{
//			Array.Reverse (bytes);
//		}
//		buf.AddRange (bytes);
//		buf.AddRange (Encoding.UTF8.GetBytes (person.name));
//
//		//写入age [4]
//		bytes = BitConverter.GetBytes (person.age);
//		if (BitConverter.IsLittleEndian)
//		{
//			Array.Reverse (bytes);
//		}
//		buf.AddRange(bytes);
//
//		//转换成功IntPtr
//		byte[] bufBytes = buf.ToArray();
//		IntPtr personData = Marshal.AllocHGlobal(bufBytes.Length);
//		Marshal.Copy(bufBytes, 0, personData, bufBytes.Length);
//
//		printPersonInfo(personData);
//
//		Marshal.FreeHGlobal(personData);

		int strLen = 0;
		IntPtr stringData = returnString(out strLen);
		if (strLen > 0)
		{
			byte[] buffer = new byte[strLen];
			Marshal.Copy(stringData, buffer, 0, strLen);
			Marshal.FreeHGlobal(stringData);

			string str = Encoding.UTF8.GetString(buffer);
			Debug.Log(str);
		}

		#endif
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}
